import 'dart:async';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_base/src/routes/common_routes.dart';
import 'package:flutter_base/src/utils/navigation_service.dart';
import 'package:flutter_base/src/utils/storage_util.dart';
import 'package:flutter_base/src/utils/toast_util.dart';
import 'package:go_router/go_router.dart';

/// 自定义网络错误
class ApiError implements Exception {
  final String message;
  final int? code;
  final dynamic data;

  ApiError(this.message, {this.code, this.data});

  @override
  String toString() => 'ApiError: $code - $message';
}

/// 网络请求拦截器
class HttpInterceptors extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
    /// 请求拦截
    // 头部添加token
    final token = await StorageUtil.getString(StorageKey.token);
    if (token != null && token.isNotEmpty) {
      options.headers["Authorization"] = "Bearer $token";
    }
    debugPrint('=================================请求信息===========================================================');
    debugPrint('发送${options.method}请求: ${options.uri}');
    debugPrint('请求头: ${options.headers}');
    debugPrint('请求参数: ${options.data}');

    // 继续请求
    handler.next(options);
  }

  @override
  Future<void> onResponse(Response response, ResponseInterceptorHandler handler) async {
    // 响应拦截
    try {
      debugPrint('收到响应: [${response.statusCode}] ${response.requestOptions.uri}');
      debugPrint('=================================请求信息===========================================================');
      // 处理HTTP状态码
      if (response.statusCode != 200) {
        _handleHttpStatusCode(response);
      }

      // 处理业务状态码
      String code = (response.data ?? {})['ErrNum']?.toString() ?? '';
      String msg = (response.data ?? {})['Msg'] ?? response.statusMessage ?? '未知错误';

      if (code == "401") {
        // 登录状态已过期
        ToastUtil.show('登录状态已过期');
        _goToLogin();
        return handler.reject(
          DioException(
            requestOptions: response.requestOptions,
            response: response,
            error: ApiError('登录状态已过期', code: 401),
            type: DioExceptionType.unknown,
          ),
        );
      } else if (code == "416") {
        // 权限已变更，请重新登录
        ToastUtil.show('权限已变更，请重新登录');
        _goToLogin();
        return handler.reject(
          DioException(
            requestOptions: response.requestOptions,
            response: response,
            error: ApiError('权限已变更，请重新登录', code: 416),
            type: DioExceptionType.unknown,
          ),
        );
      } else if (code == "500" || code == "403") {
        // 直接提示
        ToastUtil.show(msg);
      }
    } catch (e) {
      debugPrint('响应处理异常: $e');
    }

    // 请求成功时对数据做基本处理
    handler.next(response);
  }

  @override
  void onError(DioException err, ErrorInterceptorHandler handler) {
    debugPrint('请求错误: ${err.type} - ${err.message}');

    String errorTypeInfo = '网络异常';
    final exception = HttpException(err.message ?? "error message");

    switch (err.type) {
      case DioExceptionType.badResponse:
        errorTypeInfo = _getHttpErrorMessage(err.response?.statusCode ?? 0);
        break;
      case DioExceptionType.connectionTimeout:
        errorTypeInfo = '连接超时';
        break;
      case DioExceptionType.sendTimeout:
        errorTypeInfo = '请求超时';
        break;
      case DioExceptionType.receiveTimeout:
        errorTypeInfo = '响应超时';
        break;
      case DioExceptionType.cancel:
        errorTypeInfo = '请求已取消';
        break;
      case DioExceptionType.badCertificate:
        errorTypeInfo = '证书验证失败';
        break;
      case DioExceptionType.connectionError:
        errorTypeInfo = '网络连接错误';
        break;
      case DioExceptionType.unknown:
        errorTypeInfo = '未知错误';
        break;
    }

    ToastUtil.show(errorTypeInfo);
    DioException errNext = err.copyWith(error: exception);
    handler.next(errNext);
  }

  /// 处理HTTP状态码
  void _handleHttpStatusCode(Response response) {
    final statusCode = response.statusCode;

    if (statusCode == 405) {
      debugPrint('HTTP 405 错误 - 方法不被允许');
      debugPrint('请求方法: ${response.requestOptions.method}, 路径: ${response.requestOptions.path}');
      ToastUtil.show('该接口不支持${response.requestOptions.method}请求方法，请使用正确的请求方法');
    }
  }

  /// 获取HTTP错误信息
  String _getHttpErrorMessage(int statusCode) {
    switch (statusCode) {
      case 400:
        return '请求参数错误';
      case 401:
        return '未授权，请重新登录';
      case 403:
        return '服务器拒绝访问';
      case 404:
        return '请求的资源不存在';
      case 405:
        return '请求方法不被允许';
      case 408:
        return '请求超时';
      case 500:
        return '服务器内部错误';
      case 501:
        return '服务未实现';
      case 502:
        return '网关错误';
      case 503:
        return '服务不可用';
      case 504:
        return '网关超时';
      case 505:
        return 'HTTP版本不支持';
      default:
        return '未知HTTP错误($statusCode)';
    }
  }

  /// 跳转到登录页面
  void _goToLogin() {
    try {
      final context = NavigationService.navigatorKey.currentContext;
      if (context != null) {
        GoRouter.of(context).go(CommonRoutes.loginPath);
      }
    } catch (e) {
      debugPrint('跳转登录页面失败: $e');
    }
  }
}
